# coding=utf-8
import datetime
from pymongo.errors import DuplicateKeyError
import pymongo
from bson.code import Code
from blw.mapper_url import MapperUrl
import re

#url = 'mongodb://cloudbees:3fa8aa216320637832da08075220be21@paulo.mongohq.com:10028/XwmO92imxa2h6uecOuEUsA'
#dbName = 'XwmO92imxa2h6uecOuEUsA'
#url = 'mongodb://localhost:27017/'
#dbName = 'blw'
from os import environ

# Helper lambda for gracefully degrading environmental variables:
from blwpy.settings import MONGO_DB

env = lambda e, d: environ[e] if environ.has_key(e) else d
default_database = env('DJANGO_DATABASE', 'default')
print MONGO_DB[default_database]
print default_database
url= MONGO_DB[default_database]['url']
dbName = MONGO_DB[default_database]['dbName']


class MongoHelper(object):

    def __init__(self):
        self.conn = pymongo.Connection(url)
        print self.conn
        self.db = self.conn[dbName]
        print self.db.collection_names()

    def delete(self, url):
        try:
            self.db.pages.remove({'_id':url})
            print "document was removed on db.pages."
        except Exception, e:
            print str(e)

    def addPageCrawler(self, dumpData):
        try:
            self.db.pages.insert(dumpData, safe=True)
            print "document was added on db.pages."
        except DuplicateKeyError, e:
            print str(e)

    def removeDocumentByDate(self,date):
        print "size of colls %s" % str(self.db.pages.find().count())
        count = self.db.pages.find({'creation_date':{'$lt':date}}).count()
        print "size %s" % count
        self.db.pages.remove({'creation_date':{ '$lt':date}})
        print "All documents were deleted by lt creation_date: %s" % date
        print "size of colls %s" % str(self.db.pages.find().count())

    def dropCollectionColls(self, dbname):
        self.db.drop_collection(dbname)
        print "Colls was dropped."


    def findCategories(self, dictionary=None):
        reducer = Code(""" function(obj, prev){ prev.count++; prev.slug=obj.cat;  }""")
        if dictionary is not None and dictionary.has_key('tags') and not dictionary['tags'].has_key('$all'):
            dictionary.update({'tags': {'$all': self.getRegex(dictionary['tags'])}})
        categories = self.db.pages.group(key={"category": 'Recursos Humanos'}, condition=dictionary,
                                         initial={"count": 0, "slug": ''}, reduce=reducer)

        def notNone(x):
            if x['category'] is not None:
                x['count'] = int(x['count'])
                if dictionary is not None:
                    slug = MapperUrl().createUrlFilter('cat', dictionary)
                    x['slug'] = slug.replace('<value>', x['slug'])
                else:
                    x['slug'] = 'cat_' + x['slug']
                return x

        unOrderedList = map(notNone, categories)
        return sorted(unOrderedList, key=lambda category: category['count'], reverse=True)

    def findDates(self, dictionary=None):
        reducer = Code(""" function(obj, prev){ prev.count++;prev.slug=obj.date;  }""")
        if dictionary is not None and dictionary.has_key('tags') and not dictionary['tags'].has_key('$all'):
            dictionary.update({'tags': {'$all': self.getRegex(dictionary['tags'])}})
        results = self.db.pages.group(key={"date": True}, condition=dictionary, initial={"count": 0, "slug": ''},
                                      reduce=reducer)

        def notNone(x):
            if x['date'] is not None:
                x['date'] = " ".join(reversed(x['date'].split('-')[1:]))
                x['count'] = int(x['count'])
                if dictionary is not None:
                    slug = MapperUrl().createUrlFilter('date', dictionary)
                    x['slug'] = slug.replace('<value>', x['slug'])
                else:
                    x['slug'] = 'date_' + x['slug']
                return x

        unOrderedList = map(notNone, results)
        return sorted(unOrderedList, key=lambda date: date['date'], reverse=True)

    def findZones(self, dictionary=None):

        mapper = Code("""
                   function () {
                     this.zones.forEach(function(z) {
                       emit(z, 1);
                     });
                   }
                   """)
        reducer = Code("""
                    function (key, values) {
                      var total = 0;
                      for (var i = 0; i < values.length; i++) {
                        total += values[i];
                      }
                      return total;
                    }
                    """)
        if dictionary is not None and dictionary.has_key('tags') and not dictionary['tags'].has_key('$all'):
            dictionary.update({'tags': {'$all': self.getRegex(dictionary['tags'])}})
        results = self.db.pages.map_reduce(mapper, reducer, "zoneresults", query=dictionary)

        def groupByZone(doc):
            slugByZone = 'zones.desc_' + doc['_id']['desc']
            if dictionary is not None:
                slug = MapperUrl().createUrlFilter('zones.desc', dictionary)
                slugByZone = slug.replace('<value>', doc['_id']['desc'])
            return {u'zone': doc['_id']['description'], u'count': int(doc['value']), u'slug': slugByZone}

        resultsGrouped = map(groupByZone, results.find())
        return sorted(resultsGrouped, key=lambda zone: zone['count'], reverse=True)


    def findSubZones(self, dictionary=None):

        mapper = Code("""
                   function () {
                     this.szones.forEach(function(z) {
                       emit(z, 1);
                     });
                   }
                   """)
        reducer = Code("""
                    function (key, values) {
                      var total = 0;
                      for (var i = 0; i < values.length; i++) {
                        total += values[i];
                      }
                      return total;
                    }
                    """)
        if dictionary is not None and dictionary.has_key('tags') and not dictionary['tags'].has_key('$all'):
            dictionary.update({'tags': {'$all': self.getRegex(dictionary['tags'])}})
        results = self.db.pages.map_reduce(mapper, reducer, "subzonesresults", query=dictionary)

        def groupBySubZone(doc):
            slugBySZone = 'szones.desc_' + doc['_id']['desc']
            if dictionary is not None:
                slug = MapperUrl().createUrlFilter('szones.desc', dictionary)
                slugBySZone = slug.replace('<value>', doc['_id']['desc'])
            return {u'szone': doc['_id']['description'], u'count': int(doc['value']), u'slug': slugBySZone}

        resultsGrouped = map(groupBySubZone, results.find())
        return sorted(resultsGrouped, key=lambda zone: zone['count'], reverse=True)


    def findLastAdJob(self):
        return self.db.pages.find().sort([('creation_date', pymongo.DESCENDING)]).limit(40)

    def findBy(self, dictionary):
        if dictionary.has_key('tags'):
            dictionary.update({'tags': {'$all': self.getRegex(dictionary['tags'])}})
        return self.findQueryPage(dictionary, limit=40)

    def findQueryPage(self, query, limit):
        return self.db.pages.find(query).sort([('creation_date', pymongo.DESCENDING)]).limit(limit)

    def findWord(self, preffixWord, limit):
        import re
        regx = re.compile('^' + preffixWord, re.IGNORECASE)
        return self.db.words.find({'_id': {'$regex': regx}}).sort([('value', pymongo.DESCENDING)]).limit(limit)

    def countingWord(self):
        mapper = Code("""
                   function () {
                     this.tags.forEach(function(z) {
                       emit(z, 1);
                     });
                   }
                   """)
        reducer = Code("""
                    function (key, values) {
                      var total = 0;
                      for (var i = 0; i < values.length; i++) {
                        total += values[i];
                      }
                      return total;
                    }
                    """)
        return self.db.pages.map_reduce(mapper, reducer, "words", query={})

    def getRegex(self, words):
        if words:
            import urllib

            splitWords = re.findall(r"[\w']+", urllib.unquote(words).decode('utf8'))
            return splitWords
        else:
            return None
        
if __name__ == '__main__':
    mongoUtil=MongoHelper()
    #result = mongoUtil.countingWord()
    result = mongoUtil.findDates()
    print 'result'
    for doc in result:
        print doc
